package mysql

import (
	"fmt"
	"strings"
)

type ListOption struct {
	Page     int
	PageSize int
	Order    string //id desc,name asc
}

func NewListOption(page int, pageSize int, order string) (*ListOption, error) {
	l := &ListOption{}
	l.SetPage(page)
	l.SetPageSize(pageSize)
	err := l.SetOrder(order)
	return l, err
}

func (l *ListOption) SetPage(page int) {
	if page < 1 {
		page = 1
	}
	l.Page = page
}

func (l *ListOption) SetPageSize(pageSize int) {
	if pageSize < 1 {
		pageSize = 10
	} else if pageSize > 100 {
		pageSize = 100
	}
	l.PageSize = pageSize
}

func (l *ListOption) SetOrder(order string) error {
	orderStr, err := ParseOrder(order)
	if err != nil {
		return err
	}
	l.Order = orderStr
	return nil
}

func (l *ListOption) Limit() int {
	return l.PageSize
}

func (l *ListOption) Offset() int {
	return l.PageSize * (l.Page - 1)
}

func ParseOrder(order string) (string, error) {
	if order == "" {
		return "", nil
	}
	var orderFields []string
	var orderTypes []string
	fields := strings.Split(order, ",")
	for _, field := range fields {
		ft := strings.Split(field, " ")
		f := strings.TrimSpace(ft[0])
		if f == "" {
			return "", fmt.Errorf("order column is empty")
		}
		orderFields = append(orderFields, f)
		var t string
		if len(ft) > 1 {
			t = strings.ToUpper(strings.TrimSpace(ft[1]))
		}
		if t == "" || t == "1" {
			t = "ASC"
		} else if t == "-1" {
			t = "DESC"
		}
		if t != "ASC" && t != "DESC" {
			return "", fmt.Errorf("unknown order type: %s", t)
		}
		orderTypes = append(orderTypes, t)
	}
	var orderStr string
	if len(orderFields) > 0 {
		for i, f := range orderFields {
			orderStr += fmt.Sprintf("%s %s,", f, orderTypes[i])
		}
		orderStr = strings.TrimRight(orderStr, ",")
	}
	return orderStr, nil
}
